import { _decorator, Component, EventTouch, instantiate, Label, Node, Prefab, random, UITransform, v2, Vec2, Vec3, Animation, sys } from 'cc';
import { EffecLayer } from './EffecLayer';
import GameModel from './GameModel';
import { GameMainController } from './GameMainController';
import { CellView } from './CellView';
import { CELL_STATUS, CELL_WIDTH, CELL_HEIGHT, ANITIME, GRID_HEIGHT, GRID_WIDTH, GRID_PIXEL_WIDTH, GRID_PIXEL_HEIGHT, CELL_WIDTH_MARGIN, LocalStorageKey } from './ConstValue';
import { AudioMgr } from './AudioMgr';
import CellModel from './CellModel';
import { Utils } from './Utils';
const { ccclass, property } = _decorator;

@ccclass('GridView')
export class GridView extends Component {

    @property([Prefab])
    aniPre: Prefab[] = []
    @property(EffecLayer)
    private effecLayer: EffecLayer = null

    @property(Prefab)
    scoreTxt: Prefab = null
    @property(Label)
    socreLable: Label = null
    @property(Label)
    goldLable: Label = null

    private gameModel: GameModel = null
    public lastTouchPos: Vec2
    public isCanMove: boolean
    public isInPlayAni: boolean
    public controller: GameMainController
    public cellViews = null
    public curScore: number = 0// 当前总得分
    public curGold: number = 0// 本局获得金币数量
    public historyGold: number = 0// 历史金币数量

    onLoad() {
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.lastTouchPos = v2(-1, -1);
        this.isCanMove = true;
        this.isInPlayAni = false; // 是否在播放中
    }

    start() {
        this.refreshGold()
        if (this.historyGold) {
            this.goldLable.string = this.historyGold + ""
        } else {
            this.historyGold = 0
        }
    }

    public refreshGold() {
        this.historyGold = sys.localStorage.getItem(LocalStorageKey.GOLD)
    }

    public refreshScore() {
        this.curScore = 0
        this.socreLable.string = "Score:" + this.curScore
    }

    public refreshShowGold() {
        this.goldLable.string = (Number(this.historyGold) + Number(this.curGold)) + ""
    }


    update(deltaTime: number) {

    }

    onTouchStart(event: EventTouch) {
        // 获取触摸点在节点内的坐标
        let woldPoint = new Vec3(event.getUILocation().x, event.getUILocation().y, 0)
        let outPoint = new Vec3(0, 0, 0)
        this.node.getComponent(UITransform).convertToNodeSpaceAR(woldPoint, outPoint);
        var cellPos = this.convertTouchPosToCell(v2(outPoint.x, outPoint.y));
        console.log("Local Touch Start Position: ", cellPos);
        if (cellPos) {
            var changeModels = this.selectCell(cellPos);
            this.isCanMove = changeModels.length < 3;
        }
        else {
            this.isCanMove = false;
        }
    }

    onTouchMove(event: EventTouch) {
        // 获取触摸点在节点内的坐标
        if (this.isCanMove) {
            let woldPoint = new Vec3(event.getUIStartLocation().x, event.getUIStartLocation().y, 0)
            let startOutPoint = new Vec3(0, 0, 0)
            this.node.getComponent(UITransform).convertToNodeSpaceAR(woldPoint, startOutPoint);
            var startCellPos = this.convertTouchPosToCell(v2(startOutPoint.x, startOutPoint.y));

            let uiWoldPoint = new Vec3(event.getUILocation().x, event.getUILocation().y, 0)
            let uiOutPoint = new Vec3(0, 0, 0)
            this.node.getComponent(UITransform).convertToNodeSpaceAR(uiWoldPoint, uiOutPoint);
            var cellPos = this.convertTouchPosToCell(v2(uiOutPoint.x, uiOutPoint.y));
            console.debug("cellPos", cellPos)

            if (startCellPos.x != cellPos.x || startCellPos.y != cellPos.y) {
                this.isCanMove = false;
                this.selectCell(cellPos);
            }
        }
    }

    selectCell(cellPos) {
        var result = this.controller.selectCell(cellPos); // 直接先丢给model处理数据逻辑
        var changeModels = result[0]; // 有改变的cell，包含新生成的cell和生成马上摧毁的格子
        var effectsQueue = result[1]; //各种特效
        this.playEffect(effectsQueue);
        this.disableTouch(this.getStep(effectsQueue));
        this.updateView(changeModels);
        this.controller.cleanCmd();
        if (changeModels.length >= 2) {
            this.updateSelect(v2(-1, -1));
            AudioMgr.inst.playSwap();
        } else {
            this.updateSelect(cellPos);
            AudioMgr.inst.playClick();
        }
        return changeModels;
    }

    public colClean(result) {
        var changeModels = result[0]; // 有改变的cell，包含新生成的cell和生成马上摧毁的格子
        var effectsQueue = result[1]; //各种特效
        this.playEffect(effectsQueue);
        this.disableTouch(this.getStep(effectsQueue));
        this.updateView(changeModels);
        this.controller.cleanCmd();
        return changeModels;
    }

    updateSelect(pos) {
        for (var i = 1; i <= 9; i++) {
            for (var j = 1; j <= 9; j++) {
                if (this.cellViews[i][j]) {
                    var cellScript: CellView = this.cellViews[i][j].getComponent(CellView);
                    if (pos.x == j && pos.y == i) {
                        cellScript.setSelect(true);
                    }
                    else {
                        cellScript.setSelect(false);
                    }

                }
            }
        }

    }

    updateView(changeModels) {
        let eliminatingQuantity = 0
        let newCellViewInfo = [];
        let dieModel = [];
        for (var i in changeModels) {
            var model: CellModel = changeModels[i];
            var viewInfo = this.findViewByModel(model);
            var view = null;
            // 如果原来的cell不存在，则新建
            if (!viewInfo) {
                var type = model.type;
                var aniView = instantiate(this.aniPre[type]);
                aniView.parent = this.node;
                var cellViewScript = aniView.getComponent(CellView);
                cellViewScript.initWithModel(model);
                view = aniView;
            } else {   // 如果已经存在
                view = viewInfo.view;
                this.cellViews[viewInfo.y][viewInfo.x] = null;
            }
            var cellScript: CellView = view.getComponent(CellView);
            cellScript.updateView();// 执行移动动作
            if (!model.isDeath) {
                newCellViewInfo.push({
                    model: model,
                    view: view
                });
            } else {
                dieModel.push(model)
                eliminatingQuantity++;
            }
        }
        if (changeModels && changeModels.length >= 2) {
            this.getScore(eliminatingQuantity)
        }
        // 重新标记this.cellviews的信息
        newCellViewInfo.forEach(function (ele) {
            let model = ele.model;
            this.cellViews[model.y][model.x] = ele.view;
        }, this);
    }

    private getScore(eliminatingQuantity: number) {
        this.handleTimer(eliminatingQuantity)
        let randomNum = Utils.inst.getRandomInt(1, eliminatingQuantity);
        let score = randomNum * eliminatingQuantity;
        this.curScore += score
        this.handleGold(score)
        this.showScoreFab(score)
        console.debug("当前得分:" + eliminatingQuantity + " random:" + randomNum)
        this.socreLable.string = "Score:" + this.curScore
    }

    public handleGold(score: number) {
        if (score >= 50) {
            let randomNum = Utils.inst.getRandomInt(0, 2);
            if (randomNum > 0) {
                console.debug("获得一个金币")
                this.curGold += 1;
                this.goldLable.string =  (Number(this.historyGold) + Number(this.curGold)) + ""
            }
        }
    }

    public handleTimer(eliminatingQuantity: number) {
        let time = -1;
        if (eliminatingQuantity >= 21) {
            time = 5;
        } else if (eliminatingQuantity >= 18) {
            time = 4;
        } else if (eliminatingQuantity >= 15) {
            time = 3;
        } else if (eliminatingQuantity >= 9) {
            time = 2;
        } else if (eliminatingQuantity >= 3) {
            time = 1;
        }
        this.controller.adjustTimer(time)
    }

    public showScoreFab(curScore: number) {
        if (curScore <= 0) {
            return;
        }
        setTimeout(() => {
            let socreFab = instantiate(this.scoreTxt)
            socreFab.setPosition(0, 0)
            socreFab.getComponent(Label).string = curScore + ""
            let anim = socreFab.getComponent(Animation)
            anim.on(Animation.EventType.FINISHED, () => {
                socreFab.destroy();
            }, this);
            socreFab.parent = this.node.getParent();
            anim.play("scoreTxt")
        }, 500);
    }

    findViewByModel(model) {
        for (var i = 1; i <= GRID_WIDTH; i++) {
            for (var j = 1; j <= GRID_HEIGHT; j++) {
                if (this.cellViews[i][j] && this.cellViews[i][j].getComponent(CellView).model == model) {
                    return { view: this.cellViews[i][j], x: j, y: i };
                }
            }
        }
        return null;
    }

    playEffect(effectsQueue) {
        this.effecLayer.getComponent(EffecLayer).playEffects(effectsQueue);
    }

    getStep(effectsQueue) {
        if (!effectsQueue) {
            return 0;
        }
        return effectsQueue.reduce(function (maxValue, efffectCmd) {
            return Math.max(maxValue, efffectCmd.step || 0);
        }, 0);
    }

    disableTouch(step) {
        this.isInPlayAni = true;
        this.isInPlayAni = false;
        AudioMgr.inst.playContinuousMatch(step);
    }

    convertTouchPosToCell(pos: Vec2): Vec2 {
        // 需要将传入的 Vec2 转换为 Vec3，因为在 Cocos Creator 3.x 中，convertToNodeSpaceAR等方法接受和返回的是 Vec3
        if (pos.x < 0 || pos.x >= GRID_PIXEL_WIDTH || pos.y < 0 || pos.y >= GRID_PIXEL_HEIGHT) {
            return null;
        }

        const x = Math.floor((pos.x - CELL_WIDTH_MARGIN) / CELL_WIDTH) + 1;
        const y = Math.floor(pos.y / CELL_HEIGHT) + 1;
        // 返回计算后的格子坐标
        return new Vec2(x, y);
    }

    public setController(controller: GameMainController) {
        this.controller = controller;
    }

    public initWithCellModels(cellsModels) {
        this.cleanChildrenFab();
        this.cellViews = [];
        for (let i = 1; i <= GRID_WIDTH; i++) {
            this.cellViews[i] = [];
            for (var j = 1; j <= GRID_HEIGHT; j++) {
                let type = cellsModels[i][j].type;
                let aniView = instantiate(this.aniPre[type]);
                aniView.parent = this.node;
                let cellViewScript: CellView = aniView.getComponent(CellView);
                cellViewScript.initWithModel(cellsModels[i][j]);
                this.cellViews[i][j] = aniView;
            }
        }
    }

    public cleanChildrenFab() {
        const children = this.node.children;
        // 倒序遍历所有子节点，这样即使移除节点也不会影响到遍历的过程
        for (let i = children.length - 1; i >= 0; i--) {
            let child = children[i];
            // 检查子节点是否包含 CellView 组件
            if (child.getComponent('CellView')) { // 注意: 这里用字符串 'CellView' 替代之前的类引用，确保不依赖于具体实现
                child.removeFromParent();
                child.destroy();
            }
        }
    }

    public getCurScore() {
        return this.curScore;
    }

    public setCurScore(score) {
        this.curScore = score;
    }

    public getCurGold() {
        return this.curGold;
    }

    public setCurGold(gold) {
        this.curGold = gold;
    }
}


